import {
  Diff, applyPatch, applyPatches, canonicalize, convertChangesToDMP, convertChangesToXML, createPatch, createTwoFilesPatch, diffArrays, diffChars, diffCss, diffJson, diffLines, diffSentences, diffTrimmedLines, diffWords, diffWordsWithSpace, merge, parsePatch, structuredPatch
} from './jsDiff/lib/index.es6.js'


function diffCharsTest() {
  const one = 'beep boop   afff测试样本one1';
  const other = 'beepboob 2022真热样本 e ';
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffChars(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffChars error'
  }
  // console.log(`jsDiffDemo_diffChars_001: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffChars_001: ${endTime - startTime} ms`)
}



function diffWordsTest() {
  const one = 'beep boop   afff测试样本one1';
  const other = 'beepboob 2022真热样本 e ';
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffWords(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffWords error'
  }
  // console.log(`jsDiffDemo_diffWords_002: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffWords_002: ${endTime - startTime} ms`)
}




function diffWordsWithSpaceTest() {
  const one = 'beep boop   afff测 试样本one1';
  const other = 'beepboob 2022真热样本 e ';
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffWordsWithSpace(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffWordsWithSpace error'
  }
  // console.log(`jsDiffDemo_diffWordsWithSpace_003}: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffWordsWithSpace_003}: ${endTime - startTime} ms`)
}



function diffLinesTest() {
  const one = 'beep boop   afff测 试样本one1 爱啥啥啥来着';
  const other = 'beepboob 2022真热样本 e 案发飒飒afffff';
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffLines(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffLines error'
  }
  // console.log(`jsDiffDemo_diffLines_004: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffLines_004: ${endTime - startTime} ms`)
}



function diffTrimmedLinesTest() {
  const one = ' beep boop   aff哈哈  是是技术/n 撒谎还会啥杀害 ';
  const other = 'beepboob 2022真热样本 e ';
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffTrimmedLines(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffTrimmedLines error'
  }
  // console.log(`jsDiffDemo_diffTrimmedLines_005: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffTrimmedLines_005: ${endTime - startTime} ms`)
}



function diffSentencesTest() {
  const one = 'beep boop,afff哈哈,是是技术/n 撒谎还会啥杀害';
  const other = 'beepboob 2022真热样本,e? ';
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffSentences(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffSentences error'
  }
  // console.log(`jsDiffDemo_diffSentences_006: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffSentences_006: ${endTime - startTime} ms`)
}



function diffCssTest() {
  const one = '.{ width: 960px; padding: 0;}';
  const other = '#container { width: 960px; margin: auto;}';
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffCss(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffChars error'
  }
  // console.log(`jsDiffDemo_diffCss_007: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffCss_007: ${endTime - startTime} ms`)
}



function diffJsonTest() {
  const one = '[{"name":"josn1","account":1,"firstIndex":1}]';
  const other = '[{"name":"josn2","accountTwo":2,"scoundIndex":2}]';
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffJson(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffChars error'
  }
  // console.log(`jsDiffDemo_diffJson_008: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffJson_008: ${endTime - startTime} ms`)

}



function diffArraysTest() {
  const one = [1, 2, 3, 4, 5, 5, 7, 8];
  const other = [1, 2, 3, 12, 5, 5, 7, 8, 9, 10];
  let diff = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    diff = diffArrays(one, other);
  }
  let endTime = Date.now();
  if (diff.length <= 0) {
    throw 'diffChars error'
  }
  // console.log(`jsDiffDemo_diffArrays_009: ${endTime - startTime} ms`)
  print(`jsDiffDemo_diffArrays_009: ${endTime - startTime} ms`)
}



const oldFileName = 'oldFileName';
const newfileName = 'newFileName';
const oldStr = 'line2\nline3\nline4\n';
const newStr = 'line2\nline3\nline5\n';
const oldHeader = 'header1';
const newHeader = 'header2';

function createPatchTest() {
  let result = '';
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = createPatch(oldFileName, oldStr, newStr, oldHeader, newHeader);
  }
  let endTime = Date.now();
  if (result.length <= 0) {
    throw 'createPatch error'
  }
  // console.log(`jsDiffDemo_createPatch_010: ${endTime - startTime} ms`)
  print(`jsDiffDemo_createPatch_010: ${endTime - startTime} ms`)
}



function createTwoFilesPatchTest() {
  let result = '';
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = createTwoFilesPatch(oldFileName, newfileName, oldStr, newStr, oldHeader, newHeader);
  }
  let endTime = Date.now();
  if (result.length <= 0) {
    throw 'createTwoFilesPatch error'
  }
  // console.log(`jsDiffDemo_createTwoFilesPatch_011: ${endTime - startTime} ms`)
  print(`jsDiffDemo_createTwoFilesPatch_011: ${endTime - startTime} ms`)
}



function structuredPatchTest() {
  let result = undefined;
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = structuredPatch(oldFileName, newfileName, oldStr, newStr, oldHeader, newHeader);
  }
  let endTime = Date.now();
  if (result === undefined) {
    throw 'structuredPatch error'
  }
  // console.log(`jsDiffDemo_structuredPatch_012: ${endTime - startTime} ms`)
  print(`jsDiffDemo_structuredPatch_012: ${endTime - startTime} ms`)
}



function parsePatchTest() {
  const patch = createPatch(oldFileName, oldStr, newStr, oldHeader, newHeader)
  let result = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = parsePatch(patch);
  }
  let endTime = Date.now();
  if (result.length <= 0) {
    throw 'parsePatch error'
  }
  // console.log(`jsDiffDemo_parsePatch_013: ${endTime - startTime} ms`)
  print(`jsDiffDemo_parsePatch_013: ${endTime - startTime} ms`)
}



function convertChangesToXMLTest() {
  const diffResult = diffChars('New Value.', 'New ValueMoreData.');
  let result = '';
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = convertChangesToXML(diffResult);
  }
  let endTime = Date.now();
  if (result.length <= 0) {
    throw 'convertChangesToXML error'
  }
  // console.log(`jsDiffDemo_convertChangesToXML_014: ${endTime - startTime} ms`)
  print(`jsDiffDemo_convertChangesToXML_014: ${endTime - startTime} ms`)
}



function convertChangesToDMPTest() {
  const diffResult = diffChars('New Value.', 'New ValueMoreData.');
  let result = [];
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = convertChangesToDMP(diffResult);
  }
  let endTime = Date.now();
  if (result.length <= 0) {
    throw 'convertChangesToDMP error'
  }
  // console.log(`jsDiffDemo_convertChangesToDMP_015: ${endTime - startTime} ms`)
  print(`jsDiffDemo_convertChangesToDMP_015: ${endTime - startTime} ms`)
}

function canonicalizeTest() {
  let param = {
    d: 101112, c: 789, a: '123', b: 456
  }
  let result = {};
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = canonicalize(param, null, null);
  }
  let endTime = Date.now();
  if (result.d != 101112) {
    throw 'canonicalize error'
  }
  // console.log(`jsDiffDemo_canonicalize_016: ${endTime - startTime} ms`)
  print(`jsDiffDemo_canonicalize_016: ${endTime - startTime} ms`)
}



const mine =
  'Index: test\n'
  + '===================================================================\n'
  + '--- test\theader1\n'
  + '+++ test\theader2\n'
  + '@@ -1,3 +1,4 @@\n'
  + ' line2\n'
  + ' line3\n'
  + '+line4\n'
  + ' line5\n';
const theirs =
  'Index: test\n'
  + '===================================================================\n'
  + '--- test\theader1\n'
  + '+++ test\theader2\n'
  + '@@ -25,3 +25,4 @@\n'
  + ' foo2\n'
  + ' foo3\n'
  + '+foo4\n'
  + ' foo5\n';

function mergeTest() {
  let result = {};
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = merge(mine, theirs);
  }
  let endTime = Date.now();
  if (result.index != 'test') {
    throw 'merge error'
  }
  // console.log(`jsDiffDemo_merge_017: ${endTime - startTime} ms`)
  print(`jsDiffDemo_merge_017: ${endTime - startTime} ms`)
}



function applyPatchTest() {
  const patch = parsePatch(
    'Index: test\n'
    + '===================================================================\n'
    + '--- test\theader1\n'
    + '+++ test\theader2\n'
    + '@@ -1,3 +1,4 @@\n'
    + ' line2\n'
    + ' line3\n'
    + '+line4\n'
    + ' line5\n');

  let result = '';
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    result = applyPatch(
      'line2\n'
      + 'line3\n'
      + 'line5\n',
      patch[0]);
  }
  let endTime = Date.now();
  if (!result.includes('line2')) {
    throw 'applyPatch error'
  }
  // console.log(`jsDiffDemo_applyPatch_018: ${endTime - startTime} ms`)
  print(`jsDiffDemo_applyPatch_018: ${endTime - startTime} ms`)

}




class Data {
  contents = {}
  expected = {}

  loadFile(index, callback) {
    if (index.index !== undefined) {
      callback(undefined, this.contents[index.index]);
    }
  }

  patched(index, content, callback) {
    callback(this.expected);
  }

  complete(err) {
    if (err != this.expected) {
      throw 'applyPatches error'
    }
    //  expect(err).assertEqual(this.expected)
  }

  constructor(contents, expected) {
    this.contents = contents;
    this.expected = expected
  }
}

function applyPatchesTest() {
  const patch =
    'Index: test\n'
    + '===================================================================\n'
    + '--- test\theader1\n'
    + '+++ test\theader2\n'
    + '@@ -1,3 +1,4 @@\n'
    + ' line2\n'
    + ' line3\n'
    + '+line4\n'
    + ' line5\n'
    + 'Index: test2\n'
    + '===================================================================\n'
    + '--- test\theader1\n'
    + '+++ test\theader2\n'
    + '@@ -1,3 +1,4 @@\n'
    + ' foo2\n'
    + ' foo3\n'
    + '+foo4\n'
    + ' foo5\n';
  const contents = {
    test:
      'line2\n'
      + 'line3\n'
      + 'line5\n',
    test2:
      'foo2\n'
      + 'foo3\n'
      + 'foo5\n'
  };
  const expected = {
    test:
      'line2\n'
      + 'line3\n'
      + 'line4\n'
      + 'line5\n',
    test2:
      'foo2\n'
      + 'foo3\n'
      + 'foo4\n'
      + 'foo5\n'
  };
  let data = new Data(contents, expected)
  let result = '';
  let startTime = Date.now();
  for (let i = 0; i < 10000; i++) {
    applyPatches(patch, data);
  }
  let endTime = Date.now();
  // console.log(`jsDiffDemo_applyPatches_019: ${endTime - startTime} ms`)
  print(`jsDiffDemo_applyPatches_019: ${endTime - startTime} ms`)
}

function jsDiffDemoTest() {
  diffCharsTest()
  diffWordsTest()
  diffWordsWithSpaceTest()
  diffLinesTest()
  diffTrimmedLinesTest()
  diffSentencesTest()
  diffCssTest()
  diffJsonTest()
  diffArraysTest()
  createPatchTest()
  createTwoFilesPatchTest()
  structuredPatchTest()
  parsePatchTest()
  convertChangesToXMLTest()
  convertChangesToDMPTest()
  canonicalizeTest()
  mergeTest()
  applyPatchTest()
  applyPatchesTest()
}

jsDiffDemoTest()

